import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * https://gitee.com/li--jiaqiang/java-test.git
 * git pull
 * git pull origin master
 * git pull origin master --allow-unrelated-histories
 * User: 86187
 * Date: 2022-04-25
 * Time: 14:08
 */

//Scanner scan = new Scanner(System.in);

public class TestDemo2 {

    /**
     * 二分查找
     * @param nums
     * @param target
     * @param lower
     * @return
     */
    public static int binarySearch(int[] nums, int target, boolean lower) {
        int left = 0, right = nums.length - 1, ans = nums.length;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] > target || (lower && nums[mid] >= target)) { //？？？
                right = mid - 1;
                ans = mid;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }

    /**
     * 给定一个按照升序排列的整数数组 nums，和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
     * 如果数组中不存在目标值 target，返回[-1, -1]。
     * 示例 1：
     * 输入：nums = [5,7,7,8,8,10], target = 8
     * 输出：[3,4]
     *
     * 分析：
     * 直观的思路肯定是从前往后遍历一遍。用两个变量记录第一次和最后一次遇见 \textit{target}target 的下标，
     * 但这个方法的时间复杂度为 O(n)O(n)，没有利用到数组升序排列的条件。
     * 由于数组已经排序，因此整个数组是单调递增的，我们可以利用二分法来加速查找的过程。
     * 考虑target 开始和结束位置，其实我们要找的就是数组中第一个等于target 的位置（记为leftIdx）和第一个大于target 的位置减一（记为rightIdx）。
     * 二分查找中，寻找leftIdx 即为在数组中寻找第一个大于等于target 的下标，寻找 rightIdx 即为在数组中寻找第一个大于target 的下标，
     * 然后将下标减一。两者的判断条件不同，为了代码的复用，我们定义 binarySearch(nums, target, lower) 表示在nums 数组中二分查找 target 的位置，
     * 如果lower 为true，则查找第一个大于等于target 的下标，否则查找第一个大于target 的下标。
     *
     * 最后，因为target 可能不存在数组中，因此我们需要重新校验我们得到的两个下标leftIdx 和 rightIdx，看是否符合条件，
     * 如果符合条件就返回 [leftIdx,rightIdx]，不符合就返回[−1,−1]。
     *
     * 链接：https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/zai-pai-xu-shu-zu-zhong-cha-zhao-yuan-su-de-di-3-4/
     * 来源：力扣（LeetCode）
     * @param nums
     * @param target
     * @return
     */
    public static int[] searchRange(int[] nums,int target) {
        int leftIdx = binarySearch(nums, target, true); //在数组中寻找第一个大于等于target 的下标
        int rightIdx = binarySearch(nums, target, false) - 1; //数组中寻找第一个大于target 的下标，
        if (leftIdx <= rightIdx && rightIdx < nums.length && nums[leftIdx] == target && nums[rightIdx] == target) {
            return new int[]{leftIdx, rightIdx};
        }
        return new int[]{-1, -1};
    }

    public static void main(String[] args) {
        int[] nums = {5,7,7,8,8,10};

        System.out.println(Arrays.toString(searchRange(nums, 8)));
    }


}
